From: Keir Fraser Date: Fri, 23 Oct 2009 09:05:15 +0000 (+0100) Subject: xsm: Add getenforce and setenforce functionality to tools X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13182 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=0dba100da61528c1d36844a00ba2676b4712aa67;p=xen.git xsm: Add getenforce and setenforce functionality to tools This patch exposes the getenforce and setenforce functionality for the Flask XSM module. Signed-off-by : Machon Gregory Signed-off-by : George S. Coker, II --- diff --git a/tools/flask/Makefile b/tools/flask/Makefile index e78f5785db..08961cf810 100644 --- a/tools/flask/Makefile +++ b/tools/flask/Makefile @@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk SUBDIRS := SUBDIRS += libflask -SUBDIRS += loadpolicy +SUBDIRS += utils .PHONY: all clean install all clean install: %: subdirs-% diff --git a/tools/flask/libflask/flask_op.c b/tools/flask/libflask/flask_op.c index 396c0814a8..579be20d96 100644 --- a/tools/flask/libflask/flask_op.c +++ b/tools/flask/libflask/flask_op.c @@ -70,3 +70,42 @@ int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size) return 0; } + +int flask_getenforce(int xc_handle) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + int mode; + + op.cmd = FLASK_GETENFORCE; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + sscanf(buf, "%i", &mode); + + return mode; +} + +int flask_setenforce(int xc_handle, int mode) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + + op.cmd = FLASK_SETENFORCE; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%i", mode); + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + return 0; +} diff --git a/tools/flask/libflask/include/flask.h b/tools/flask/libflask/include/flask.h index 5241f7a2a0..31f6263404 100644 --- a/tools/flask/libflask/include/flask.h +++ b/tools/flask/libflask/include/flask.h @@ -18,5 +18,7 @@ int flask_load(int xc_handle, char *buf, uint32_t size); int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t *sid); int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size); +int flask_getenforce(int xc_handle); +int flask_setenforce(int xc_handle, int mode); #endif /* __FLASK_H__ */ diff --git a/tools/flask/loadpolicy/Makefile b/tools/flask/loadpolicy/Makefile deleted file mode 100644 index 8b404214c2..0000000000 --- a/tools/flask/loadpolicy/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -XEN_ROOT=../../.. -include $(XEN_ROOT)/tools/Rules.mk -XEN_LIBXC = $(XEN_ROOT)/tools/libxc - -LIBXC_ROOT = $(XEN_ROOT)/tools/libxc -LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask - -PROFILE=#-pg -BASECFLAGS=-Wall -g -Werror -BASECFLAGS+= $(PROFILE) -#BASECFLAGS+= -I$(XEN_ROOT)/tools -BASECFLAGS+= $(CFLAGS_libxenctrl) -BASECFLAGS+= -I$(LIBFLASK_ROOT)/include -BASECFLAGS+= -I. - -CFLAGS += $(BASECFLAGS) -LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT) -TESTDIR = testsuite/tmp -TESTFLAGS= -DTESTING -TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR) - -CLIENTS := flask-loadpolicy -CLIENTS_SRCS := $(patsubst flask-%,%.c,$(CLIENTS)) -CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS)) - -.PHONY: all -all: $(CLIENTS) - -$(CLIENTS): flask-%: %.o - $(CC) $(CFLAGS) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -L. -lflask $(LDFLAGS_libxenctrl) -o $@ - -$(CLIENTS_OBJS): $(CLIENTS_SRCS) - $(COMPILE.c) -o $@ $< - -.PHONY: clean -clean: - rm -f *.o *.opic *.so - rm -f $(CLIENTS) - $(RM) $(DEPS) - -.PHONY: print-dir -print-dir: - @echo -n tools/flask/loadpolicy: - -.PHONY: print-end -print-end: - @echo - -.PHONY: install -install: all - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)$(SBINDIR) - --include $(DEPS) - -# never delete any intermediate files. -.SECONDARY: diff --git a/tools/flask/loadpolicy/loadpolicy.c b/tools/flask/loadpolicy/loadpolicy.c deleted file mode 100644 index bb6eeb8de5..0000000000 --- a/tools/flask/loadpolicy/loadpolicy.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * - * Authors: Michael LeMay, - * George Coker, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USE_MMAP - -static void usage (int argCnt, const char *args[]) -{ - fprintf(stderr, "Usage: %s \n", args[0]); - exit(1); -} - -int main (int argCnt, const char *args[]) -{ - const char *polFName; - int polFd = 0; - void *polMem = NULL; - void *polMemCp = NULL; - struct stat info; - int ret; - int xch = 0; - - if (argCnt != 2) - usage(argCnt, args); - - polFName = args[1]; - polFd = open(polFName, O_RDONLY); - if ( polFd < 0 ) - { - fprintf(stderr, "Error occurred opening policy file '%s': %s\n", - polFName, strerror(errno)); - ret = -1; - goto cleanup; - } - - ret = stat(polFName, &info); - if ( ret < 0 ) - { - fprintf(stderr, "Error occurred retrieving information about" - "policy file '%s': %s\n", polFName, strerror(errno)); - goto cleanup; - } - - polMemCp = malloc(info.st_size); - -#ifdef USE_MMAP - polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0); - if ( !polMem ) - { - fprintf(stderr, "Error occurred mapping policy file in memory: %s\n", - strerror(errno)); - ret = -1; - goto cleanup; - } - - xch = xc_interface_open(); - if ( xch < 0 ) - { - fprintf(stderr, "Unable to create interface to xenctrl: %s\n", - strerror(errno)); - ret = -1; - goto cleanup; - } - - memcpy(polMemCp, polMem, info.st_size); -#else - ret = read(polFd, polMemCp, info.st_size); - if ( ret < 0 ) - { - fprintf(stderr, "Unable to read new Flask policy file: %s\n", - strerror(errno)); - goto cleanup; - } - else - { - printf("Read %d bytes from policy file '%s'.\n", ret, polFName); - } -#endif - - ret = flask_load(xch, polMemCp, info.st_size); - if ( ret < 0 ) - { - errno = -ret; - fprintf(stderr, "Unable to load new Flask policy: %s\n", - strerror(errno)); - ret = -1; - goto cleanup; - } - else - { - printf("Successfully loaded policy.\n"); - } - -done: - if ( polMemCp ) - free(polMemCp); - if ( polMem ) - { - ret = munmap(polMem, info.st_size); - if ( ret < 0 ) - fprintf(stderr, "Unable to unmap policy memory: %s\n", strerror(errno)); - } - if ( polFd ) - close(polFd); - if ( xch ) - xc_interface_close(xch); - - return ret; - -cleanup: - goto done; -} diff --git a/tools/flask/utils/Makefile b/tools/flask/utils/Makefile new file mode 100644 index 0000000000..0908f51443 --- /dev/null +++ b/tools/flask/utils/Makefile @@ -0,0 +1,54 @@ +XEN_ROOT=../../.. +include $(XEN_ROOT)/tools/Rules.mk +XEN_LIBXC = $(XEN_ROOT)/tools/libxc + +LIBXC_ROOT = $(XEN_ROOT)/tools/libxc +LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask + +PROFILE=#-pg +BASECFLAGS=-Wall -g -Werror +BASECFLAGS+= $(PROFILE) +#BASECFLAGS+= -I$(XEN_ROOT)/tools +BASECFLAGS+= $(CFLAGS_libxenctrl) +BASECFLAGS+= -I$(LIBFLASK_ROOT)/include +BASECFLAGS+= -I. + +CFLAGS += $(BASECFLAGS) +LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT) +TESTDIR = testsuite/tmp +TESTFLAGS= -DTESTING +TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR) + +CLIENTS := flask-loadpolicy flask-setenforce flask-getenforce +CLIENTS_SRCS := $(patsubst flask-%,%.c,$(CLIENTS)) +CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS)) + +.PHONY: all +all: $(CLIENTS) + +$(CLIENTS): flask-%: %.o + $(CC) $(CFLAGS) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -L. -lflask $(LDFLAGS_libxenctrl) -o $@ + +.PHONY: clean +clean: + rm -f *.o *.opic *.so + rm -f $(CLIENTS) + $(RM) $(DEPS) + +.PHONY: print-dir +print-dir: + @echo -n tools/flask/utils: + +.PHONY: print-end +print-end: + @echo + +.PHONY: install +install: all + $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) + $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)$(SBINDIR) + +-include $(DEPS) + +# never delete any intermediate files. +.SECONDARY: diff --git a/tools/flask/utils/getenforce.c b/tools/flask/utils/getenforce.c new file mode 100644 index 0000000000..9960434ac8 --- /dev/null +++ b/tools/flask/utils/getenforce.c @@ -0,0 +1,66 @@ +/* + * + * Author: Machon Gregory, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void usage (int argCnt, const char *args[]) +{ + fprintf(stderr, "Usage: %s\n", args[0]); + exit(1); +} + +int main (int argCnt, const char *args[]) +{ + int ret; + int xch = 0; + + if (argCnt != 1) + usage(argCnt, args); + + xch = xc_interface_open(); + if ( xch < 0 ) + { + fprintf(stderr, "Unable to create interface to xenctrl: %s\n", + strerror(errno)); + ret = -1; + goto done; + } + + ret = flask_getenforce(xch); + if ( ret < 0 ) + { + errno = -ret; + fprintf(stderr, "Unable to get enforcing mode: %s\n", + strerror(errno)); + ret = -1; + goto done; + } + else + { + if(ret) + printf("Enforcing\n"); + else + printf("Permissive\n"); + } + +done: + if ( xch ) + xc_interface_close(xch); + + return ret; +} diff --git a/tools/flask/utils/loadpolicy.c b/tools/flask/utils/loadpolicy.c new file mode 100644 index 0000000000..bb6eeb8de5 --- /dev/null +++ b/tools/flask/utils/loadpolicy.c @@ -0,0 +1,129 @@ +/* + * + * Authors: Michael LeMay, + * George Coker, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_MMAP + +static void usage (int argCnt, const char *args[]) +{ + fprintf(stderr, "Usage: %s \n", args[0]); + exit(1); +} + +int main (int argCnt, const char *args[]) +{ + const char *polFName; + int polFd = 0; + void *polMem = NULL; + void *polMemCp = NULL; + struct stat info; + int ret; + int xch = 0; + + if (argCnt != 2) + usage(argCnt, args); + + polFName = args[1]; + polFd = open(polFName, O_RDONLY); + if ( polFd < 0 ) + { + fprintf(stderr, "Error occurred opening policy file '%s': %s\n", + polFName, strerror(errno)); + ret = -1; + goto cleanup; + } + + ret = stat(polFName, &info); + if ( ret < 0 ) + { + fprintf(stderr, "Error occurred retrieving information about" + "policy file '%s': %s\n", polFName, strerror(errno)); + goto cleanup; + } + + polMemCp = malloc(info.st_size); + +#ifdef USE_MMAP + polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0); + if ( !polMem ) + { + fprintf(stderr, "Error occurred mapping policy file in memory: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } + + xch = xc_interface_open(); + if ( xch < 0 ) + { + fprintf(stderr, "Unable to create interface to xenctrl: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } + + memcpy(polMemCp, polMem, info.st_size); +#else + ret = read(polFd, polMemCp, info.st_size); + if ( ret < 0 ) + { + fprintf(stderr, "Unable to read new Flask policy file: %s\n", + strerror(errno)); + goto cleanup; + } + else + { + printf("Read %d bytes from policy file '%s'.\n", ret, polFName); + } +#endif + + ret = flask_load(xch, polMemCp, info.st_size); + if ( ret < 0 ) + { + errno = -ret; + fprintf(stderr, "Unable to load new Flask policy: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } + else + { + printf("Successfully loaded policy.\n"); + } + +done: + if ( polMemCp ) + free(polMemCp); + if ( polMem ) + { + ret = munmap(polMem, info.st_size); + if ( ret < 0 ) + fprintf(stderr, "Unable to unmap policy memory: %s\n", strerror(errno)); + } + if ( polFd ) + close(polFd); + if ( xch ) + xc_interface_close(xch); + + return ret; + +cleanup: + goto done; +} diff --git a/tools/flask/utils/setenforce.c b/tools/flask/utils/setenforce.c new file mode 100644 index 0000000000..91fb3594aa --- /dev/null +++ b/tools/flask/utils/setenforce.c @@ -0,0 +1,73 @@ +/* + * + * Authors: Machon Gregory, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void usage (int argCnt, const char *args[]) +{ + fprintf(stderr, "Usage: %s [ (Enforcing|1) | (Permissive|0) ]\n", args[0]); + exit(1); +} + +int main (int argCnt, const char *args[]) +{ + int ret = 0; + int xch = 0; + long mode = 0; + char *end; + + if (argCnt != 2) + usage(argCnt, args); + + xch = xc_interface_open(); + if ( xch < 0 ) + { + fprintf(stderr, "Unable to create interface to xenctrl: %s\n", + strerror(errno)); + ret = -1; + goto done; + } + + if( strlen(args[1]) == 1 && (args[1][0] == '0' || args[1][0] == '1')){ + mode = strtol(args[1], &end, 10); + ret = flask_setenforce(xch, mode); + } else { + if( strcasecmp(args[1], "enforcing") == 0 ){ + ret = flask_setenforce(xch, 1); + } else if( strcasecmp(args[1], "permissive") == 0 ){ + ret = flask_setenforce(xch, 0); + } else { + usage(argCnt, args); + } + } + + if ( ret < 0 ) + { + errno = -ret; + fprintf(stderr, "Unable to get enforcing mode: %s\n", + strerror(errno)); + ret = -1; + goto done; + } + +done: + if ( xch ) + xc_interface_close(xch); + + return ret; +} diff --git a/tools/python/xen/lowlevel/flask/flask.c b/tools/python/xen/lowlevel/flask/flask.c index 02ad04d422..bb42b5ce8f 100644 --- a/tools/python/xen/lowlevel/flask/flask.c +++ b/tools/python/xen/lowlevel/flask/flask.c @@ -136,6 +136,60 @@ static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds) return Py_BuildValue("i", ret); } +static PyObject *pyflask_getenforce(PyObject *self) +{ + int xc_handle; + int ret; + + xc_handle = xc_interface_open(); + if (xc_handle < 0) { + errno = xc_handle; + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = flask_getenforce(xc_handle); + + xc_interface_close(xc_handle); + + if ( ret < 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_setenforce(PyObject *self, PyObject *args, + PyObject *kwds) +{ + int xc_handle; + int mode; + int ret; + + static char *kwd_list[] = { "mode", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &mode) ) + return NULL; + + xc_handle = xc_interface_open(); + if (xc_handle < 0) { + errno = xc_handle; + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = flask_setenforce(xc_handle, mode); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + static PyMethodDef pyflask_methods[] = { { "flask_context_to_sid", (PyCFunction)pyflask_context_to_sid, @@ -158,6 +212,18 @@ static PyMethodDef pyflask_methods[] = { " policy [str]: policy to be load\n" "Returns: [int]: 0 on success; -1 on failure.\n" }, + { "flask_getenforce", + (PyCFunction)pyflask_getenforce, + METH_NOARGS, "\n" + "Returns the current mode of the Flask XSM module.\n" + "Returns: [int]: 0 for permissive; 1 for enforcing; -1 on failure.\n" }, + + { "flask_setenforce", + (PyCFunction)pyflask_setenforce, + METH_KEYWORDS, "\n" + "Modifies the current mode for the Flask XSM module.\n" + " mode [int]: mode to change to\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, { NULL, NULL, 0, NULL } }; diff --git a/tools/python/xen/util/xsm/flask/flask.py b/tools/python/xen/util/xsm/flask/flask.py index 906b537d77..83d662d98a 100644 --- a/tools/python/xen/util/xsm/flask/flask.py +++ b/tools/python/xen/util/xsm/flask/flask.py @@ -7,10 +7,11 @@ from xen.xend import sxp #Functions exported through XML-RPC xmlrpc_exports = [ 'on', - 'set_policy' + 'set_policy', + 'getenforce', + 'setenforce' ] - def err(msg): """Raise XSM-Flask exception. """ @@ -56,3 +57,9 @@ def get_security_label(self, xspol=None): def set_policy(xs_type, policy_b64, flags=None, overwrite=None): policy = base64.b64decode(policy_b64); return flask.flask_load(policy), "" + +def getenforce(): + return flask.flask_getenforce() + +def setenforce(mode): + return flask.flask_setenforce(mode) diff --git a/tools/python/xen/xend/XendXSPolicy.py b/tools/python/xen/xend/XendXSPolicy.py index 5fb1635faf..dd508d9b9e 100644 --- a/tools/python/xen/xend/XendXSPolicy.py +++ b/tools/python/xen/xend/XendXSPolicy.py @@ -49,7 +49,9 @@ class XendXSPolicy(XendBase): 'get_resource_label', 'set_resource_label', 'get_labeled_resources', - 'can_run' ] + 'can_run', + 'getenforce', + 'setenforce'] return XendBase.getFuncs() + funcs getClass = classmethod(getClass) @@ -205,6 +207,12 @@ class XendXSPolicy(XendBase): raise SecurityError(irc) return security.check_can_run(sec_label) + def getenforce(self): + return security.getenforce() + + def setenforce(self, mode): + return security.setenforce(mode) + get_xstype = classmethod(get_xstype) get_xspolicy = classmethod(get_xspolicy) set_xspolicy = classmethod(set_xspolicy) @@ -214,6 +222,8 @@ class XendXSPolicy(XendBase): get_resource_label = classmethod(get_resource_label) get_labeled_resources = classmethod(get_labeled_resources) can_run = classmethod(can_run) + getenforce = classmethod(getenforce) + setenforce = classmethod(setenforce) class XendACMPolicy(XendXSPolicy): diff --git a/tools/python/xen/xm/getenforce.py b/tools/python/xen/xm/getenforce.py new file mode 100644 index 0000000000..526be82e7f --- /dev/null +++ b/tools/python/xen/xm/getenforce.py @@ -0,0 +1,66 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Author: Machon Gregory +#============================================================================ + +"""Get the current mode of the Flask XSM module. +""" + +from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server +from xen.util import xsconstants + +def help(): + return """ + Usage: xm getenforce + + Returns the current mode (Permissive, Enforcing) of the + Flask XSM module.""" + +def getenforce(): + if xm_main.serverType == xm_main.SERVER_XEN_API: + if xsconstants.XS_POLICY_FLASK != \ + int(server.xenapi.XSPolicy.get_xstype()): + raise OptionError("Unsupported policy type") + mode = int(server.xenapi.XSPolicy.getenforce()) + else: + if server.xend.security.on() != xsconstants.XS_POLICY_FLASK: + raise OptionError("Unsupported policy type") + mode = server.xend.security.getenforce() + + if mode == 0: + print "Permissive" + elif mode == 1: + print "Enforcing" + +def main(argv): + if "-?" in argv: + help() + return + + if len(argv) != 1: + raise OptionError("No arguments expected.") + + getenforce() + +if __name__ == '__main__': + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) + + diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 94236a6ab7..e570f8eebe 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -225,8 +225,7 @@ SUBCOMMAND_HELP = { # security - 'addlabel' : ('